package com.ddzh.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 分页拦截器
 */
@Configuration
public class PageHelperConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
    /*
    为什么加了这个分页插件之后就能帮我们进行分页了呢？
    public class PaginationInterceptor extends AbstractSqlParserHandler implements Interceptor
    看到这个分页插件 PaginationInterceptor 本质是一个拦截器（同时也是一个SQL语句解析的处理器）
    Interceptor：是什么？本质是mybatis的一个插件拦截器接口=》即mybatis所有的插件都会实现Interceptor接口
    如黑马旅游中分页插件是在 sqlSessionFactory 中加的

    1. 那么这里是如何实现将 PaginationInterceptor 插件加入到 sqlSessionFactory 呢？=》springboot的自动装配

    =》自动装配起点：spring.factories文件，
    =》扫描 key=EnableAutoConfiguration的全路径 的 所有value，并自动装入IoC容器中
    PS：自动装配时，是扫描当前包下的所有spring.factories文件，
        将所有的key=EnableAutoConfiguration的全路径 的 所有value对应的对象都装入IoC容器中

    2. 如何将对象都装入IoC容器中？？
    这里需要用到的是MybatisPlusAutoConfiguration==》入口，进去看一下
    public class MybatisPlusAutoConfiguration implements InitializingBean {
        //从源码可以看出：可以自动注入集合 / 数组等复杂数据类型 如果自定义实现复杂类型注入用@Autowired
        //这里是用构造注入的方式注入的
        private final Interceptor[] interceptors;

        //创建 SqlSessionFactory 以前我们自己配置属性，现在springboot帮我们配置
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            //其他参数省略，在构造函数中初始化插件（拦截器）
            public MybatisPlusAutoConfiguration(ObjectProvider<Interceptor[]> interceptorsProvider) {
                this.interceptors = interceptorsProvider.getIfAvailable();
            }

     3. //向 SqlSessionFactory 中加入我们的插件，插件就可以使用了，插件this.interceptors从哪来，上面的构造函数
            if (!ObjectUtils.isEmpty(this.interceptors)) {
                factory.setPlugins(this.interceptors);
            }
        }
    }

    4. 有了插件，拦截器如何使用他呢？？
        进入 PaginationInterceptor 类中
        public class PaginationInterceptor extends AbstractSqlParserHandler implements Interceptor {
            //在方法执行之前进行拦截（方法执行之前有一个before）
            @Override
            public Object intercept(Invocation invocation) throws Throwable {


            }

        }


       //拦截器接口
       public interface Interceptor {
            //对方法进行拦截，相当于方法之前的before增强
            Object intercept(Invocation var1) throws Throwable;

            default Object plugin(Object target) {
                return Plugin.wrap(target, this);
            }

            default void setProperties(Properties properties) {
        }
}

     */
}
